package com.typhoon.rpc.registry.db;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import com.typhoon.rpc.common.util.CollectionUtil;
import com.typhoon.rpc.registry.ServiceDiscovery;
import com.typhoon.rpc.registry.db.entity.ApiNode;
import com.typhoon.rpc.registry.db.util.DataSourceUtils;

public class DBServiceDiscovery implements ServiceDiscovery {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DBServiceDiscovery.class);
	
	private JdbcTemplate jdbcTempalte = DataSourceUtils.getJdbcTemplate();

	@Override
	public String discover(String serviceName) {
		List<ApiNode> nodeList = this.queryAvailableList(serviceName);
        if (CollectionUtil.isEmpty(nodeList)) {//没有可用的服务实例(尚未有服务注册,或者服务宕机不可用)
            throw new RuntimeException(String.format("can not find any address node on interface: %s", serviceName));
        }
        String address;
        int size = nodeList.size();
        if (size == 1) {//如果只有一个服务,获取该地址
            // 若只有一个地址，则获取该地址
            address = nodeList.get(0).getHostAddress();
            LOGGER.debug("get only address node: {}", address);
        } else {//如果有多个服务实例,随机获取,(根据有种负载策略获取)
            // 若存在多个地址，则随机获取一个地址
            address = nodeList.get(ThreadLocalRandom.current().nextInt(size)).getHostAddress();
            LOGGER.debug("get random address node: {}", address);
        }
		return address;
	}

	/**
	 * 获取可用服务列表
	 * 
	 * @param serviceName
	 * @return
	 */
	private List<ApiNode> queryAvailableList(String serviceName) {
		StringBuilder sql = new StringBuilder();
		sql.append("	select	");
		sql.append("		*	");
		sql.append("	from	");
		sql.append("		ApiNode	");
		sql.append("	where	");
		sql.append("		interfaceName = ?	");
		return this.jdbcTempalte.query(sql.toString(), BeanPropertyRowMapper.newInstance(ApiNode.class), serviceName);
	}

}
